package com.grandtech.oss.api;

import com.grandtech.oss.module.entity.OSSMaterialInfoResult;
import com.grandtech.oss.module.model.OSSInformation;
import com.grandtech.oss.service.OSSInformationService;
import com.grandtech.oss.service.OSSMaterialInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/api/v1/oss/package")
public class PackageApplication {
    /**
     * @apiDefine package package（多文件打包成压缩文件下载）
     */

    @Autowired
    OSSInformationService ossInformationService;
    @Autowired
    OSSMaterialInfoService ossMaterialInfoService;

    /**
     * @api {post} /api/v1/oss/package/packageByUUID packageByUUID（传入uuid打包下载文件）
     * @apiName packageByUUID
     * @apiGroup package
     * @apiVersion 1.0.0
     *
     * @apiParam {list} body 传入要打包下载的文件的uuid
     * @apiParamExample {json} Request-Example:
     * {
     *     ["4765c5e5bdff49578a08795bc24e991e","4ac76329d7a148ce94c5f85f4a344e21","5928943563d8439da350cafecae6e875","ce4e9bbae01b48e49fcb202648daac59"]
     * }
     *
     * @apiSuccess {zip} success 下载zip
     */
    @PostMapping("/packageByUUID")
    public void packageByUUID(@RequestBody List<String> uuids, HttpServletResponse response) {
        String filename = formatFileName("");
        try {
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "utf-8"));

            OSSInformation ossInformation = ossInformationService.queryOne();
            String root = ossInformation.getRoot();

            List<OSSMaterialInfoResult> ossMaterialInfoResultList = ossMaterialInfoService.queryByUUID(uuids);
            Map<String, String> originFileNames = new HashMap<>();
            List<File> fileList = new ArrayList<>();
            for (int i = 0; i < ossMaterialInfoResultList.size(); i++) {
                String storePath = ossMaterialInfoResultList.get(i).getStorePath();
                fileList.add(new File(root + storePath));
                // originFileNames.put(ossMaterialInfoResultList.get(i).getId(), ossMaterialInfoResultList.get(i).getOriginalName());
                originFileNames.put(storePath.substring(storePath.lastIndexOf("/") + 1, storePath.length())
                        , ossMaterialInfoResultList.get(i).getOriginalName());
            }
            modifyRepeatFileName(originFileNames);
            ZipUtils.toZip(fileList, originFileNames, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /***
     * @api {post} /api/v1/oss/packageByUserApp packageByUserApp（传入开发者和应用打包下载文件）
     * @apiName packageByUserApp
     * @apiGroup package
     * @apiVersion 1.0.0
     *
     * @apiParam {String} [appcode] 应用代码
     * @apiParam {String} [appname] 应用名称
     * @apiParam {String} [developer] 开发者名字
     * @apiParamExample {json} Request-Example:
     * {
     *     "appcode":"app_meilc_1",
     *     "appname":"app_meilc_1",
     *     "developer":"meilc"
     * }
     *
     * @apiSuccess {zip} success 下载zip
     */
    @PostMapping("/packageByUserApp")
    public void queryByUserApplication(@RequestParam(required = false) String appcode,
                                       @RequestParam(required = false) String appname,
                                       @RequestParam(required = false) String developer,
                                       HttpServletResponse response) {
        String filename = formatFileName("");
        try {
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "utf-8"));

            OSSInformation ossInformation = ossInformationService.queryOne();
            String root = ossInformation.getRoot();
            HashMap<String, String> params = new HashMap<>();
            params.put("appcode", appcode);
            params.put("appname", appname);
            params.put("developer", developer);
            List<OSSMaterialInfoResult> ossMaterialInfoResultList = ossMaterialInfoService.queryByUserApplication(params);
            Map<String, String> originFileNames = new HashMap<>();
            List<File> fileList = new ArrayList<>();
            for (int i = 0; i < ossMaterialInfoResultList.size(); i++) {
                String storePath = ossMaterialInfoResultList.get(i).getStorePath();
                fileList.add(new File(root + storePath));
                // originFileNames.put(ossMaterialInfoResultList.get(i).getId(), ossMaterialInfoResultList.get(i).getOriginalName());
                originFileNames.put(storePath.substring(storePath.lastIndexOf("/") + 1, storePath.length())
                        , ossMaterialInfoResultList.get(i).getOriginalName());
            }
            modifyRepeatFileName(originFileNames);
            ZipUtils.toZip(fileList, originFileNames, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件名重复处理（加括号和数字后缀）
     *
     * @param fileNames
     * @return
     */
    private Map<String, String> modifyRepeatFileName(Map<String, String> fileNames) {
        Map<String, String> lists = new HashMap<>();
        fileNames.forEach((key, v) -> {
            if (lists.get(v) != null) {
                String b = v.substring(v.lastIndexOf("."), v.length());//后缀(带.)
                String a = v.replaceAll(b, "");//名称

                Integer index = 1;
                while (lists.get(a + "(" + index + ")" + b) != null) {
                    index++;
                }
                fileNames.put(key, a + "(" + index + ")" + b);
                lists.put(a + "(" + index + ")" + b, "");
            } else {
                lists.put(v, "");
            }
        });
        return fileNames;
    }

    /***
     * @api {post} /api/v1/oss/zipdir zipdir（传入服务器路径打包下载文件）
     * @apiName zipdir
     * @apiGroup package
     * @apiVersion 1.0.0
     *
     * @apiParam {String} dir 文件夹路径
     * @apiParam {bool} [KeepDirStructure] 保持目录结构（默认false，重名时会出错，未处理）
     * @apiParamExample {json} Request-Example:
     * {
     *     "dir":"D:\nginx\html\files\app_meilc_1\model_1",
     *     "KeepDirStructure":"false"
     * }
     *
     * @apiSuccess {zip} success 下载zip
     */
    @PostMapping("/zipdir")
    public void zipdir(@RequestParam String dir,
                       @RequestParam(defaultValue = "false", required = false) boolean KeepDirStructure,
                       HttpServletResponse response) {
        String filename = formatFileName("");
        try {
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "utf-8"));
            ZipUtils.toZip(dir, response.getOutputStream(), KeepDirStructure);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件名处理
     *
     * @param filename
     * @return
     */
    private String formatFileName(String filename) {
        if (filename == null || filename.trim().equals("")) {
            String timeformat = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            filename = timeformat + ".zip";
        } else if (!filename.contains(".")) {
            filename += ".zip";
        }
        return filename;
    }


}
